home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / raytrace / pov / gen / animdat / symtab.c < prev    next >
C/C++ Source or Header  |  1992-07-22  |  5KB  |  199 lines

  1. /*--------------------------------------------------------------*/
  2. /*            ANIMDAT 1.1                */
  3. /*        copyright 1992 - TODD SANKEY            */
  4. /*                                */
  5. /*  The author hereby grants permission for the use and sharing    */
  6. /* of both source code end executable versions of this software    */
  7. /* at no charge. This software is not for sale and no other    */
  8. /* shall charge for it without the expressed consent of the    */
  9. /* author.                            */
  10. /*                                */
  11. /*  The source code can be freely modified, but it must retain    */
  12. /* the original copyright notice, and the author must be    */
  13. /* notified of these changes if the altered code is to be    */
  14. /* distributed.                            */
  15. /*--------------------------------------------------------------*/
  16. /*------------------------------------------------------*/
  17. /* symtab.c    Routines for interfacing to a symbol    */
  18. /*        table organized as a binary tree.    */
  19. /*------------------------------------------------------*/
  20.  
  21. #include <string.h>
  22. #include <stdio.h>
  23. #include "common.h"
  24.  
  25. /*------------------------------------------------------*/
  26. /* alloc_symbol        Allocate a symbol node.        */
  27. /*------------------------------------------------------*/
  28. static sym_ptr alloc_symbol()
  29. {
  30.  sym_ptr sp;
  31.  
  32.  sp = (sym_ptr)malloc(sizeof(sym));
  33.  if (sp == NULL)
  34.     error(FAILED_MALLOC,NULL);
  35.  
  36.  sp->left = NULL;
  37.  sp->right = NULL;
  38.  sp->name = NULL;
  39.  sp->sym_info = NULL;
  40.  return (sp);
  41. }
  42.  
  43.  
  44. /*------------------------------------------------------*/
  45. /* search_symtab    Search a symbol table for a    */
  46. /*            named symbol.            */
  47. /*------------------------------------------------------*/
  48. sym_ptr search_symtab(sym_ptr symtab, char *name)
  49. {
  50.  int comp;
  51.  
  52.  if (symtab!=NULL)
  53.     do {
  54.         comp=strcmp(name,symtab->name);
  55.         if (comp < 0)
  56.             symtab = symtab->left;
  57.         else if (comp > 0)
  58.             symtab = symtab->right;
  59.         } while (comp && symtab!=NULL);
  60.  
  61.  return (symtab);
  62. }
  63.  
  64. /*------------------------------------------------------*/
  65. /* add_symbol        Add a symbol to a symbol table    */
  66. /*            provided an equivalently named    */
  67. /*            symbol does not already exist.    */
  68. /*------------------------------------------------------*/
  69. sym_ptr add_symbol(sym_ptr *symtab, char *name)
  70. {
  71.  sym_ptr sp,osp;
  72.  int comp;
  73.  
  74.  if ((*symtab) == NULL) {
  75.     *symtab = alloc_symbol();
  76.     sp = (*symtab);
  77.     }
  78.  
  79.  else {
  80.     sp = (*symtab);
  81.     do {
  82.         comp=strcmp(name,sp->name);
  83.         osp = sp;
  84.         if (comp < 0)
  85.             sp = sp->left;
  86.         else if (comp > 0)
  87.             sp = sp->right;
  88.         } while (comp && (sp != NULL) );
  89.  
  90.     if (comp < 0) {
  91.         osp->left = alloc_symbol();
  92.         sp = osp->left;
  93.         }
  94.     else if (comp > 0) {
  95.         osp->right = alloc_symbol();
  96.         sp = osp->right;
  97.         }
  98.     else
  99.         error(SYMBOL_REDEFINED,name);
  100.     }
  101.  
  102.  sp->name = (char *)malloc(strlen(name)+1);
  103.  strcpy(sp->name,name);
  104.  
  105.  return (sp);
  106. }
  107.  
  108.  
  109.  
  110.  
  111. /*------------------------------------------------------*/
  112. /* traverse_symtab    Call a function once for each    */
  113. /*            node in a symbol table.        */
  114. /*------------------------------------------------------*/
  115. void traverse_symtab(sym_ptr symtab,void (*f)(sym_ptr symbol))
  116. {
  117.  if (symtab != NULL) {
  118.     traverse_symtab(symtab->left,f);
  119.     (*f)(symtab);
  120.     traverse_symtab(symtab->right,f);
  121.     }
  122. }
  123.  
  124.  
  125.  
  126. /*------------------------------------------------------*/
  127. /* display_symbol    Display a symbol's name.    */
  128. /*------------------------------------------------------*/
  129. static void display_symbol(sym_ptr symbol)
  130. {
  131.  printf(" %s",symbol->name);
  132. }
  133.  
  134.  
  135. /*------------------------------------------------------*/
  136. /* display_symtab    Display every name in a symbol    */
  137. /*            table.                */
  138. /*------------------------------------------------------*/
  139. void display_symtab(sym_ptr symtab)
  140. {
  141.  traverse_symtab(symtab,display_symbol);
  142. }
  143.  
  144.  
  145.  
  146. /*------------------------------------------------------*/
  147. /* eval_symbol        Evaluate a mathematical symbol. */
  148. /*------------------------------------------------------*/
  149. double eval_symbol(char *name)
  150. {
  151.  sym_ptr symbol;
  152.  
  153.  symbol = search_symtab(symbol_table,name);
  154.  if (symbol == NULL)
  155.     error(UNDEFINED_SYMBOL,name);
  156.  
  157.  if (!symbol->update_flag) {
  158.     symbol->update_flag = 1;
  159.     switch (symbol->sym_type) {
  160.         case SYM_DOUBLE :
  161.             symbol->cur_val = eval_btree((btree_node_ptr)(symbol->sym_info));
  162.             break;
  163.         case SYM_FILE :
  164.             fscanf((FILE *)symbol->sym_info,"%lf",&(symbol->cur_val));
  165.             break;
  166.         default :
  167.             sprintf(cur_line,"Symbol -%s- could not be evaluated numerically",name);
  168.             error(SYNTAX_ERROR,cur_line);
  169.         }
  170.     }
  171.  
  172.  return (symbol->cur_val);
  173. }
  174.  
  175.  
  176. /*------------------------------------------------------*/
  177. /* print_symbol        Print the value for a symbol    */
  178. /*            of any type.            */
  179. /*------------------------------------------------------*/
  180. void print_symbol(FILE *ofile,char *name)
  181. {
  182.  sym_ptr symbol;
  183.  
  184.  symbol = search_symtab(symbol_table, name);
  185.  if (symbol == NULL)
  186.     error(UNDEFINED_SYMBOL, name);
  187.  
  188.  switch (symbol->sym_type) {
  189.     case SYM_DOUBLE:
  190.     case SYM_FILE:
  191.             fprintf(ofile,"%lf",eval_symbol(name));
  192.             break;
  193.     case SYM_STRING:
  194.             fprintf(ofile,"%s",(char *)symbol->sym_info);
  195.             break;
  196.     default:
  197.             error(SYNTAX_ERROR,"Bad symbol type");
  198.     }
  199. }